Dataset

White-throated sparrows are a common winter songbird throughout the southern United States. As the name suggests, they are easily recognizable by their white throats. Their song is an iconic whistle often described as “O Sweet Canada.” They can be found in woods, forest edges, shrubby fields, and at bird feeders. White-throated sparrows have tan striped and white striped color morphs which differ in behavior.

Emerald Hill is a popular daytime hangout for white-throated sparrows. Several individuals have been tagged with telemetry units to understand their movement patterns and habitat use. For this exercise, I will be looking at the home range of the individual 1E2D334C who I have nicknamed Nugget.

First, I will take a quick look at the spread of the data to check for any outliers.

qaqc_plot <- ggplot() + geom_point(data=nugget, aes(utm_easting,utm_northing), color = "orange2") +
                        labs(x="Easting", y="Northing") +
                        guides(color=guide_legend("Identifier"))

ggplotly(qaqc_plot)

Minimum Convex Polygon

Next, I will look at the home range of Nugget. For this analysis I am using minimum convex polygon to determine the minimum bounding geometry of the space used by Nugget.

## Data for a single individual
nugget_df <- as.data.frame(nugget)
xy <- c(as.data.frame(nugget_df$utm_easting),as.data.frame(nugget_df$utm_northing))
xy <- as.data.frame(xy)

## projecting the data to UTM
data.proj <- SpatialPointsDataFrame(xy,nugget_df, proj4string = CRS("+proj=utm +zone=16 +datum=WGS84 +units=m +no_defs"))
xy.sp <- SpatialPoints(data.proj@coords)

## MCP analysis
mcp.out <- mcp(xy.sp, percent=100, unout="ha")

## converting mcp to sf object for ggplot and points to df
mcp.sf <- st_as_sf(mcp.out)
mcp.points <- cbind((data.frame(xy)),nugget_df$individual.local.identifier)
colnames(mcp.points) <- c("x","y", "identifier")

# MCP plot
mcp.plot <- ggplot() + theme_bw() +
  theme(axis.text.y = element_text(angle = 90, hjust = 0.5, vjust = 0.5)) + 
  theme(panel.grid = element_blank()) +
  geom_spatial_rgb(data = emerald.hill, aes(x=x, y=y, r=red, g=green, b=blue)) +
  geom_sf(data=mcp.sf, alpha = 0.3) +
  geom_point(data=mcp.points, aes(x=x, y=y), color = "orange2")  +
  labs(x="Easting (m)", y="Northing (m)", title=mcp.points$identifier) +
  theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5), panel.grid = element_blank()) 

mcp.plot + annotate("text", x = 467400, y = 4043640, label = paste(round(mcp.out@data$area,2),"ha"), 
                    fontface = "bold", size = 5, color = "white")

It appears that Nugget uses a small portion of emerald hill about 10 ha in size mostly in wooded areas. Some of Nugget’s range extends into the mowed lawn of Emerald Hill and the residential neighborhood next door.

Kernel-Density Estimation

Which areas does Nugget use more? Let’s look at Nugget’s frequency of use with kernel-density estimation. I used 95% KDE (blue), 75% KDE (green), and 50% KDE (yellow).

x <- as.data.frame(nugget_df$utm_easting)
y <- as.data.frame(nugget_df$utm_northing)
xy <- c(x,y)

## projecting the data to UTM
data.proj <- SpatialPointsDataFrame(xy,nugget_df, proj4string = CRS("+proj=utm +zone=16 +datum=WGS84 +units=m +no_defs"))
xy.sp <- SpatialPoints(data.proj@coords)

## KDE analysis at 95, 85, 75
kde<-kernelUD(xy.sp, h="href", kern="bivnorm", grid=100)
ver95 <- getverticeshr(kde, 95)
ver85 <- getverticeshr(kde, 85)
ver75 <- getverticeshr(kde, 75)
ver50 <- getverticeshr(kde, 50)

## converting to sf object and df
kde.points <- cbind((data.frame(data.proj@coords)),nugget_df$individual.local.identifier)
colnames(kde.points) <- c("x","y","identifier")
kde95.sf <- st_as_sf(ver95)
kde85.sf <- st_as_sf(ver85)
kde75.sf <- st_as_sf(ver75)
kde50.sf <- st_as_sf(ver50)

##making the plot
kde.plot <- ggplot() + theme_bw() +
  theme(axis.text.y = element_text(angle = 90, hjust = 0.5, vjust = 0.5)) + 
  geom_spatial_rgb(data = emerald.hill, aes(x=x, y=y, r=red, g=green, b=blue)) +
   geom_point(data=kde.points, aes(x=x, y=y), color = "lightgray") +
  geom_sf(data=kde95.sf, fill = "blue", alpha = 0.4) +
  geom_sf(data=kde75.sf, fill = "green", alpha = 0.3) +
  geom_sf(data=kde50.sf, fill = "yellow", alpha = 0.2)  +
  labs(x="Easting (m)", y="Northing (m)", title=kde.points$identifier) +
  theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5), panel.grid = element_blank()) + 
  scale_y_continuous(n.breaks = 4)
  
kde.plot <- kde.plot + annotate("text", x = 467500, y = 4043640, label = paste("95% ",round(ver95$area,2),"ha"), 
                    fontface = "bold", size = 5, color = "white") 
 
kde.only.plot <- ggplot() + theme_bw() +
  theme(axis.text.y = element_text(angle = 90, hjust = 0.5, vjust = 0.5)) + 
  geom_spatial_rgb(data = emerald.hill, aes(x=x, y=y, r=red, g=green, b=blue)) +
  geom_sf(data=kde95.sf, fill = "blue", alpha = 0.4) +
  geom_sf(data=kde75.sf, fill = "green", alpha = 0.3) +
  geom_sf(data=kde50.sf, fill = "yellow", alpha = 0.2)  +
  labs(x="Easting (m)", y="Northing (m)", title=kde.points$identifier) +
  theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5), panel.grid = element_blank()) + 
  scale_y_continuous(n.breaks = 4)

kde.only.plot <- kde.only.plot + annotate("text", x = 467500, y = 4043640, label = paste("95%",round(ver95$area,2),"ha"),
                    fontface = "bold", size = 5, color = "white") 

kde.plot + kde.only.plot 

Using a 95% KDE, Nuggets range shrinks by half from 9.85 ha to 4.36 ha.


MCP vs KDE

Now let’s compare the minimum convex polygon to the kernel-density estimation to get a feel of where Nugget likes to hang out at Emerald Hill. As seen from the map, Nugget prefers to spend time in the woods in the eastern portion of Emerald Hill. It is interesting to note that Nugget spends 50% of their time on an area less than 1 ha. Going forward, it would be interesting to see how the ranges of other sparrows on Emerald Hill overlap with Nugget.

Continuous-Time Movement Modeling

Now I will look at how the home range estimation changes when I account for the time between data points.

# read in original dataset and filter to individual
sparrow2 <- read.csv("locationsll.csv")
nugget2 <- sparrow2 %>% 
  filter(individual.local.identifier == "1E2D334C")

# convert to telemetry data
nugget.telem <- as.telemetry(nugget2, 
                             coords = c("x", "y"),
                               projection = "+proj=utm +zone=16 +datum=WGS84 +units=m +no_defs")

# calculate fit object
nugget.guess <- ctmm.guess(nugget.telem, interactive=FALSE)

# compute akde and get summary information, note this will take time to run code
nugget.ouf <- ctmm.fit(nugget.telem, nugget.guess)
wAKDE.nugget <- akde(nugget.telem, nugget.ouf, weights=TRUE)

The graph shows the weighted autocorrelated kernel density estimate (wAKDE) which estimates the animal’s space use while accounting for location error and temporal autocorrelation. Nugget’s wAKDE is very flat indicating mostly regular fixes on the GPS. The sudden rise at the right of the graph indicates a few long gaps occurred where the GPS lost signal. This is probably due to Nugget leaving Emerald Hill in the evening to go sleep in another location.

# for home range estimate CI
summary(wAKDE.nugget)
## $DOF
##      area bandwidth 
##  2259.809 20480.890 
## 
## $CI
##                      low      est     high
## area (hectares) 4.545649 4.739046 4.936415
## 
## attr(,"class")
## [1] "area"
# clean simple version
wAKDE1 <- plot(wAKDE.nugget)

From this graph, we can see that the confidence interval for the 95% range is close together. This is likely due to the high number of data points we have for Nugget.

# convert to SPDF to convert to sf object for plotting in ggplot
ud.sp <- SpatialPolygonsDataFrame.UD(wAKDE.nugget)
ud.sf <- st_as_sf(ud.sp)

nugget.sf <- st_as_sf(nugget_df, coords = c("utm_easting","utm_northing")) %>% st_set_crs(32647)

# adke summary data
akde.summary <- summary(wAKDE.nugget)
akde.summary[["CI"]][3]
## [1] 4.936415

The 95% KDE from before estimated the home range at 9.36 ha which is slightly smaller but very similar to the ctmm 95% home range estimation. Let’s see how the ctmm home range fits on Emerald Hill.

Comparison of Methods

Lastly, let’s compare all the home range estimates used in this exercise.